﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework.Storage;
using System.IO;
using Microsoft.Xna.Framework;
using System.Xml.Serialization;

using _XNA__RunningDeath.GLO;
using _XNA__RunningDeath.BUS.VatThe;

namespace _XNA__RunningDeath.DAO
{
    public struct SaveGameData
    {
        public string PlayerName;                       //Tên Nhân vật
        public int Life;                                //Mạng sống của nhân vật
        public int Score;                               //Điểm của nhân vật
        public DateTime Date;                           //Thời điểm lưu
        public int speedAt;                             //Tốc độ của các vật thể
        public Vector2 PointActor;                 //tọa độ của nhân vật
        public Vector2 pointBeMat01;                    //tọa độ của bề mặt
        public Vector2 pointBeMat02;                    //tọa độ của bề mặt
        public Vector2 pointBeMat03;                    //tọa độ của bề mặt
        public Rectangle recHo;                         //rectangle Hố
        public Vector2 pointDa;                         //tọa độ của Đá

        public string fileName;                         //Tên file lưu

        //public List<CChuoi_BUS> danhSachChuoi ;
    }


    public class SaveGame
    {
        static IAsyncResult asyncResult;
        static StorageDevice storageDevice;
        static PlayerIndex playerIndex = PlayerIndex.One;
        static SaveGameData noData;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filename"> "savegame.sav"</param>
        /// <param name="data">Dữ Liệu truyền vào</param>
        public static bool doSave(string filename, SaveGameData data)
        {
            try
            {
                asyncResult = StorageDevice.BeginShowSelector(playerIndex, null, null);
                storageDevice = StorageDevice.EndShowSelector(asyncResult);

                IAsyncResult result = storageDevice.BeginOpenContainer("SaveGame", null, null);
                result.AsyncWaitHandle.WaitOne();
                StorageContainer container = storageDevice.EndOpenContainer(result);

                result.AsyncWaitHandle.Close();
            
                if (container != null)
                {
                    if (container.FileExists(filename))
                    {
                        container.DeleteFile(filename);
                    }

                    string[] arrFileName = container.GetFileNames();
                    if (arrFileName.Count() > 4)
                        doRemoveMin();

                    using (Stream stream = container.CreateFile(filename))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));
                        serializer.Serialize(stream, data);
                        stream.Close();
                    }
                }
                container.Dispose();
                container = null;

                return true;
            }
            catch
            {
                return false;
            }
        }


        private static void doRemoveMin()
        {
            loadArrData();
            List<SaveGameData> dsData = CGLOBAL.arrDataGame;

            int min = 0;
            for (int i = 1; i < dsData.Count; i++)
            {
                if (dsData[i].Date <= dsData[min].Date)
                {
                    min = i;
                }
            }

            doDelete(dsData[min].fileName);
            dsData.RemoveAt(min);
            CGLOBAL.arrDataGame = dsData;
        }

        public static void doDelete(string filename)
        {
            try
            {
                asyncResult = StorageDevice.BeginShowSelector(playerIndex, null, null);
                storageDevice = StorageDevice.EndShowSelector(asyncResult);

                IAsyncResult result = storageDevice.BeginOpenContainer("SaveGame", null, null);
                result.AsyncWaitHandle.WaitOne();
                StorageContainer container = storageDevice.EndOpenContainer(result);

                result.AsyncWaitHandle.Close();

                if (container != null)
                {
                    if (container.FileExists(filename))
                    {
                        container.DeleteFile(filename);
                    }
                }
                container.Dispose();
                container = null;
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// Đọc và trả về Dữ liệu game đã lưu
        /// </summary>
        /// <param name="filename">Tên file đã lưu</param>
        /// <returns></returns>
        public static SaveGameData doLoad(string filename)
        {
            try
            {
                asyncResult = StorageDevice.BeginShowSelector(playerIndex, null, null);
                storageDevice = StorageDevice.EndShowSelector(asyncResult);

                IAsyncResult result = storageDevice.BeginOpenContainer("SaveGame", null, null);
                result.AsyncWaitHandle.WaitOne();
                StorageContainer container = storageDevice.EndOpenContainer(result);

                result.AsyncWaitHandle.Close();

                string []file = container.GetFileNames();

                foreach(string item in file)
                {
                    
                }

                if (container != null)
                {
                    if (!container.FileExists(filename))
                    {
                        // If not, dispose of the container and return.
                        container.Dispose();
                    }
                    else
                    {

                        // Open the file.
                        Stream stream = container.OpenFile(filename, FileMode.Open);

                        // Convert the object to XML data and put it in the stream.
                        XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));

                        SaveGameData data = (SaveGameData)serializer.Deserialize(stream);
                        
                        stream.Close();

                        // Dispose the container, to commit the data.
                        container.Dispose();
                        return data;
                    }
                }
                container.Dispose();
                container = null;
            }
            catch
            {
            }
            noData.Life = -1;
            return noData;
        }


        public static void loadArrData()
        {
            CGLOBAL.arrDataGame.Clear();
            try
            {
                asyncResult = StorageDevice.BeginShowSelector(playerIndex, null, null);
                storageDevice = StorageDevice.EndShowSelector(asyncResult);

                IAsyncResult result = storageDevice.BeginOpenContainer("SaveGame", null, null);
                result.AsyncWaitHandle.WaitOne();
                StorageContainer container = storageDevice.EndOpenContainer(result);

                result.AsyncWaitHandle.Close();

                if (container != null)
                {
                    string[] arrFileName = container.GetFileNames();

                    foreach (string filename in arrFileName)
                    {
                        if (!container.FileExists(filename))
                        {
                            container.Dispose();
                            return;
                        }
                        else
                        {
                            Stream stream = container.OpenFile(filename, FileMode.Open);

                            XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));

                            SaveGameData data = (SaveGameData)serializer.Deserialize(stream);

                            CGLOBAL.arrDataGame.Add(data);

                            stream.Close();
                        }
                    }
                    container.Dispose();
                    container = null;
                }else
                {
                    container.Dispose();
                    container = null;
                }
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

        private static void doOpenFile(StorageDevice device, string filename)
        {
            // Open a storage container.
            IAsyncResult result = device.BeginOpenContainer("StorageDemo", null, null);
            //Chờ đợi cho việc chờ xử lý để trở thành tín hiệu. Wait for the Wait Handle to become signaled.
            result.AsyncWaitHandle.WaitOne();

            StorageContainer container = device.EndOpenContainer(result);
            // Close the wait handle.
            result.AsyncWaitHandle.Close();

            // Add the container path to our file name.
            filename = "savegame.sav";
            // Check to see whether the save exists.
            if (!container.FileExists(filename))
            {
                // If not, dispose of the container and return.
                container.Dispose();
                return;
            }

            // Open the file.
            Stream stream = container.OpenFile(filename, FileMode.Open);

            // Convert the object to XML data and put it in the stream.
            XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));

            SaveGameData data = (SaveGameData)serializer.Deserialize(stream);

            stream.Close();

            // Dispose the container, to commit the data.
            container.Dispose();
        } 
    }
}
